﻿package PinballCode {
	import flash.display.Shape;
	import flash.geom.*
     import flash.display.*
	
	// Bumper class
	public class Bumper extends Shape {
		
		private var score:int; 						//score associated with it
		private var radius:Number;     					// radius from center of polygon
		private var center:Vertex;    				 // center of polygon
		private var sides:Number;     					 // number of sides
		private var color:uint;        					// color of polygon
		private var oCenterColor:uint = 0xD5D5D7;  			 // original color of center polygon		
		private var centerColor:uint;			 		  // color of center polygon
		private var thickness:Number;  						// thickness of outer line
		private var centerThickness:Number = 1; 			 // thickness of outer line
		private var vertices:Array;    						// array of polygon vertices
		private var centerVertices:Array;					// center vertices used for animation
		private var centerRadiusFraction:Number = .85;		// center radius factor
		private var hollow:Boolean;   						 // is the polygon hollow?
		private var lineColor:Number = 0x000000;			// color of the lines
		private var hitThickness:int = 3;					// thickness when hit
		public var walls:Array;	
		private var deformed:Boolean;
		private var scaledAmount:Number = 1;
		
		
		// Gradient color varibles
		var fillType:String = GradientType.LINEAR;	// creates fill type
   		var colors:Array = [0xE1E1E1, 0x6B6B6B];	// colors used
		//var colors:Array = [0xFF0000, 0x0000FF];
    	var alphas:Array = [1, 1];						// alphas of each color
    	var ratios:Array = [0x00, 0xFF];				// ration in distance from each other for each color
     	var matr:Matrix = new Matrix();					// matrixs used
     	var spreadMethod:String = SpreadMethod.REFLECT;	// how the spread is layed out
		
		var startT:Number;								// when animation starts
		
		private var animationTimer:Number = 0;			// time per animation
		private var animationGap:int = 20;				// limit of time gap
		
		private var cTimeSinceHit:Number = 0;
		
		private var animateObj:Boolean;		// checks if it should redraw on scree


		//propertys
		public function get Score():int { return score; }
		
		// constructor
		public function Bumper(sides:uint, radius:Number, center:Vertex, score:uint = 100, thickness:Number=2, color:uint=0xff0000, hollow:Boolean=false) {
			this.sides = sides;
			this.center = new Vertex(0,0);
			this.radius = radius;
			this.color = color;
			this.thickness = thickness;
			this.hollow = hollow;
			this.score = score;
			this.center = center;
			vertices = new Array();
			centerVertices = new Array();
			centerColor = oCenterColor;
			startT = radius*centerRadiusFraction;
			walls = new Array();
			matr.createGradientBox(radius*centerRadiusFraction,radius*centerRadiusFraction,45,startT,startT);
			init();
		}
		
		public function init():void {
			makeVertices();
			renderVertices();
		}
		
		// calculate and store polygon vertices:
		public function makeVertices():void {
			vertices.push(new Vertex(center.x+radius,center.y)); // start polygon on x=radius and y=0 from center
			centerVertices.push(new Vertex(center.x+(radius * centerRadiusFraction),center.y));
			// calculate vertices for angles between 0 and 360, not inclusive--already have 1st vertex, which closes polygon)
			for (var side:uint=1; side < sides; side++) {
				var angle:Number = 2*Math.PI*side / sides; // how many angle increments from 0
				vertices.push(new Vertex(center.x+radius*Math.cos(angle),center.y+radius*Math.sin(angle)));
				walls.push(new Wall(vertices[side - 1],vertices[side]));
				centerVertices.push(new Vertex(center.x+(radius * centerRadiusFraction)*Math.cos(angle),center.y+(radius * centerRadiusFraction)*Math.sin(angle)));
			}
			walls.push(new Wall(vertices[vertices.length - 1],vertices[0]));
			
			
		}
		
		// render the polygon:
		public function renderVertices():void {
			
			// set fill and hollowness:
			graphics.beginFill(color,alpha=(hollow?0:1));
			
			// set border:
			graphics.lineStyle(thickness,lineColor,alpha=1);
			
			// start at this vertex (x=radius,y=0 from center)
			graphics.moveTo(Vertex(vertices[0]).x, Vertex(vertices[0]).y);
			
			// draw line to each vertex going clockwise from starting vertex:
			for(var side:uint=1; side < sides; side++) {
				graphics.lineTo(Vertex(vertices[side]).x, Vertex(vertices[side]).y);
			}
			
			// connect the last vertex to starting vertex:
			graphics.lineTo(Vertex(vertices[0]).x, Vertex(vertices[0]).y);
			
			
			
			graphics.beginGradientFill(fillType, colors, alphas, ratios, matr, spreadMethod);
			
			// set border:
			graphics.lineStyle(centerThickness,lineColor,alpha=1);
			
			// start at this vertex (x=radius,y=0 from center)
			graphics.moveTo(Vertex(centerVertices[0]).x, Vertex(centerVertices[0]).y);
			
			// draw line to each vertex going clockwise from starting vertex:
			for(side =1; side < sides; side++) {
				graphics.lineTo(Vertex(centerVertices[side]).x, Vertex(centerVertices[side]).y);
			}
			
			// connect the last vertex to starting vertex:
			graphics.lineTo(Vertex(centerVertices[0]).x, Vertex(centerVertices[0]).y);
			
			
			// done:
			graphics.endFill();
		}
		public function animate(dt:Number)
		{
			animateObj = false;
			animationTimer += dt;
			if(deformed)
			{
				if(cTimeSinceHit > .5) {
					cTimeSinceHit = 0;
					deformed = false;
					scaledAmount = 1/scaledAmount;
				}
				if(cTimeSinceHit == 0) {
				scale();
				animateObj = true;
				}
				
				
				cTimeSinceHit += dt;
			}		
			if(animationTimer > animationGap)
			{
				matr.tx += 50*dt;
				//trace(matr.tx);
				if(matr.tx > 90)
				{
					matr.tx = startT;
					animationTimer = 0;
				}
				animateObj = true;
			}
			if(animateObj)
			{
				graphics.clear();
				renderVertices();
			}
		}
		
		public function collision():void {
			if(!deformed) {
				scaledAmount = 1.2;
				deformed = true;
				cTimeSinceHit = 0;
			}
		}
		
		public function scale():void {
			// must be along coordinate axes
			var angle:Number=Math.atan2(vertices[1].y-vertices[0].y,
								        vertices[1].x-vertices[0].x);
			graphics.clear();
			rotate(-angle,false); 

			for (var i:int=0; i < vertices.length; i++) {
				vertices[i].x -= center.x;
				vertices[i].y -= center.y
			}
			
			for (var j:int=0; j < vertices.length; j++) {
				vertices[j].x *= scaledAmount;
				vertices[j].y *= scaledAmount;
			}
			
			for (var k:int=0; k < vertices.length; k++) {
				vertices[k].x += center.x;
				vertices[k].y += center.y;
			}
			
			rotate(angle,false); // rotate back
			
		}
		
		public function rotate(angle:Number,degrees:Boolean):void {
			for (var i:int=0; i < vertices.length; i++) {
				vertices[i].x -= center.x;
				vertices[i].y -= center.y;
			}
			
			for (var j:int=0; j < vertices.length; j++) {
				vertices[j] = Vertex.rotate(angle,degrees,vertices[j]);
			}
			
			for (var k:int=0; k < vertices.length; k++) {
				vertices[k].x += center.x;
				vertices[k].y += center.y;
			}
			

		}
		
		
		
		
	}
}